Amazon ConnectでCloudWatchのアラームを電話通知してみた
はじめに
CX事業本部の高橋雄大です。
AWSリソースの監視にはCloudWatchを利用することが多いですが、通知の手段は多岐にわたります。今回はAmazon Connectを活用した電話通知の方法を紹介します。
Amazon Connectとは?
Amazon Connectはクラウド型のコンタクトセンター(コールセンター)です。単純な電話の受発信だけでなく、問い合わせフロー設計による対応の自動化や、他のAWSサービスとの連携が簡単にできます。
料金は電話番号の利用料と分単位の従量課金のみで初期費用は不要です。
Amazon Connect(クラウドベースのコンタクトセンター)| AWS
実装してみた
Amazon ConnectはLambda関数から実行することが可能です。CloudWatchのアラームをSNSからLambdaで受け取り、Lambda関数からAWS SDKを利用してAmazon Connectの問い合わせフローを実行します。
コンタクトセンターの準備
Amazon ConnectはCloudFormationに対応していないため、AWSのマネージメントコンソールから環境を構築する必要があります。以下の記事を参考に、インスタンスの作成から電話番号の取得まで行います。
問い合わせフローの作成
Amazon Connectの問い合わせフローを作成します。以下の図が問い合わせフローの完成形になります。
CloudWatchアラームで検知したエラー内容を通知したいので、「音声の設定」と「プロンプトの再生」を設定します。プロンプトの再生では、どのような形式でメッセージを受け取るのか選択します。
Lambdaが送信したテキストを再生する場合は、以下のようにプロンプトの再生を設定をしてください。
- プロンプト: テキスト読み上げ機能 (アドホック)&動的に入力する
- タイプ: ユーザー定義
- 属性: message
- 解釈する: テキスト
運用監視の実装
環境
以下の環境で実装をしています。
- Lambdaランタイム: Python3.7
- Region: ap-northeast-1
- AWS CLI: 1.16.170
ディレクトリ構成
srcディレクトリにLambda関数のソースコードを配置しています。
├─ src │ └─ lambda │ ├─ call_error_message.py │ └─ run_error.py └─ template.yaml
Lambda関数
SNSからメッセージを受け取り、Amazon Connectの問い合わせフローを実行するLambda関数です。
意図的に例外を返却して、CloudWatchでアラームを発生させるLambda関数です。
def lambda_handler(event: dict, context: dict) -> None: raise Exception('Error!')
テンプレート
Lambda関数とCloudWatchとSNSをCloudFormationでデプロイするためのテンプレートです。CloudWatchのアラームは、RunErrorFunctionで1分間に1回以上のエラーが発生した場合に検知するよう設定しています。
AWSTemplateFormatVersion: '2010-09-09' Transform: AWS::Serverless-2016-10-31 Parameters: ProjectName: Type: String DestinationPhoneNumber: Type: String SourcePhoneNumber: Type: String InstanceId: Type: String ContactFlowId: Type: String Globals: Function: Runtime: python3.7 MemorySize: 128 Timeout: 10 Environment: Variables: TZ: Asia/Tokyo Resources: LambdaExecutionRole: Type: AWS::IAM::Role Properties: AssumeRolePolicyDocument: Statement: - Effect: Allow Principal: Service: lambda.amazonaws.com Action: - sts:AssumeRole Path: / Policies: - PolicyName: Fn::Sub: ${ProjectName}-lambda-execution-role PolicyDocument: Statement: - Effect: Allow Action: - logs:CreateLogGroup - logs:CreateLogStream - logs:PutLogEvents Resource: '*' - Effect: Allow Action: - sns:Publish Resource: '*' - Effect: Allow Action: - connect:StartOutboundVoiceContact - connect:StopContact Resource: '*' CallErrorMessageFunction: Type: AWS::Serverless::Function Properties: FunctionName: Fn::Sub: ${ProjectName}-call-error-message CodeUri: src/lambda Handler: call_error_message.lambda_handler Role: Fn::GetAtt: - LambdaExecutionRole - Arn Environment: Variables: DestinationPhoneNumber: Ref: DestinationPhoneNumber SourcePhoneNumber: Ref: SourcePhoneNumber InstanceId: Ref: InstanceId ContactFlowId: Ref: ContactFlowId Events: CloudWatchAlarmTopic: Type: SNS Properties: Topic: Ref: CloudWatchAlarmTopic RunErrorFunction: Type: AWS::Serverless::Function Properties: FunctionName: Fn::Sub: ${ProjectName}-run-error CodeUri: src/lambda Handler: run_error.lambda_handler Role: Fn::GetAtt: - LambdaExecutionRole - Arn ErrorsAlarm: Type: AWS::CloudWatch::Alarm Properties: AlarmName: Fn::Sub: ${ProjectName}-errors Namespace: AWS/Lambda Dimensions: - Name: FunctionName Value: !Sub ${ProjectName}-run-error MetricName: Errors ComparisonOperator: GreaterThanOrEqualToThreshold Period: 60 EvaluationPeriods: 1 Statistic: Sum Threshold: 1 AlarmActions: - Ref: CloudWatchAlarmTopic TreatMissingData: notBreaching CloudWatchAlarmTopic: Type: AWS::SNS::Topic Properties: DisplayName: Fn::Sub: ${ProjectName}-cloud-watch-alarm TopicName: Fn::Sub: ${ProjectName}-cloud-watch-alarm
環境変数の設定
デプロイで利用する環境変数を設定します。
export PROJECT_NAME='cloudwatch-amazon-connect' #プロジェクト名 export AWS_ACCOUNT_ID='' #AWSアカウントID export REGION='ap-northeast-1' #リージョン export DESTINATION_PHONE_NUMBER='+819000000000' #通知先の電話番号 export SOURCE_PHONE_NUMBER='+815000000000' #取得した電話番号 export INSTANCE_ID='' #インスタンスID export CONTACT_FLOW_ID='' #コンタクトフローID
インスタンスIDとコンタクトフローIDは、Amazon Connectの問い合わせフロー作成画面から確認できます。「追加フロー情報」もしくは「URL」のArnから取得してください。
arn:aws:connect:{AWS::Region}:{AWS::AccountId}:instance/{インスタンスID}/contact-flow/{コンタクトフローID}
S3バケットの作成
パッケージ化したソースコードをアップロードするためのS3バケットを作成します。
aws s3api create-bucket \ --bucket ${PROJECT_NAME}-artifact-${AWS_ACCOUNT_ID} \ --region ${REGION} \ --create-bucket-configuration LocationConstraint=${REGION}
パッケージ
ソースコードをパッケージ化します。
aws cloudformation package \ --template-file template.yaml \ --output-template-file template-output.yaml \ --s3-bucket ${PROJECT_NAME}-artifact-${AWS_ACCOUNT_ID}
デプロイ
CloudFormationのテンプレートに記載した各リソースをデプロイします。
aws cloudformation deploy \ --template-file template-output.yaml \ --stack-name ${PROJECT_NAME}-stack \ --parameter-overrides \ ProjectName=${PROJECT_NAME} \ DestinationPhoneNumber=${DESTINATION_PHONE_NUMBER} \ SourcePhoneNumber=${SOURCE_PHONE_NUMBER} \ InstanceId=${INSTANCE_ID} \ ContactFlowId=${CONTACT_FLOW_ID} \ --no-fail-on-empty-changeset \ --capabilities CAPABILITY_NAMED_IAM
動作確認
RunErrorFunction
を実行して意図的にエラーを発生させます。
aws lambda invoke log \ --invocation-type Event \ --function-name ${PROJECT_NAME}-run-error \ --region ${REGION} \ --payload '{}'
電話通知のみ実行する場合はCallErrorMessageFunction
を実行します。
aws lambda invoke log \ --invocation-type Event \ --function-name ${PROJECT_NAME}-call-error-message \ --region ${REGION} \ --payload '{"Records": [{"Sns": {"Message": "{\"AWSAccountId\": \"12345\"}"}}]}'
通知先の電話番号に音声通知が届けば成功です。
まとめ
CloudWatchアラームの内容をLambdaから簡単に電話で通知することができました。Amazon Connectは他にも様々な機能を備えています。例えば、電話の受信者にプッシュ番号を入力してもらい、Lambda関数で番号に応じた処理を実行することも可能です。
次回はAmazon ConnectからLambda関数を実行させる方法について記事を書こうと思います。